package falcon.common;

import java.util.Calendar;

public final class Log {
	
	public static void log(Throwable exception, String format, Object... args) {
		Throwable throwable = new Throwable();
		StackTraceElement logInvoker = throwable.getStackTrace()[1];
		slog(logInvoker, exception, format, args);
	}
	
	public static void log(String format, Object... args) {
		Throwable throwable = new Throwable();
		StackTraceElement logInvoker = throwable.getStackTrace()[1];
		slog(logInvoker, null, format, args);
	}
	
	private static void slog(StackTraceElement logInvoker, Throwable exception, String format, Object... args) {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		StringBuilder sb = new StringBuilder(128);
		sb.append(String.format("%04d-%02d-%02d", year, month, day));
		sb.append(' ');
		sb.append(String.format("%02d:%02d:%02d", hour, minute, second));
		sb.append(' ');
		if (exception != null) {
			sb.append(exception.toString());
			sb.append(" at ");
			// 打印Exp堆栈信息
			int tab = sb.length();
			StackTraceElement[] invokers = exception.getStackTrace();
			int count = Math.min(4, invokers.length);
			for (int i = 0; i < count; i ++) {
				StackTraceElement invoker = invokers[i];
				if (i == count - 1) {
					sb.append("...");
				} else {
					String className = invoker.getClassName();
					String methodName = invoker.getMethodName();
					int lineNumber = invoker.getLineNumber();
					sb.append(String.format("%s.%s:%d\n", className, methodName, lineNumber));
				}
				for (int x = 0; x < tab; x ++) {
					sb.append(' ');
				}
			}
		}
		// 打印Log堆栈信息
		String className = logInvoker.getClassName();
		String methodName = logInvoker.getMethodName();
		int lineNumber = logInvoker.getLineNumber();
		sb.append(String.format("%s.%s:%d", className, methodName, lineNumber));
		sb.append(' ');
		sb.append(String.format(format, args));
		sb.append('\n');
		System.out.print(sb.toString());
	}
}
